/**

This file is part of MaCI/GIMnet.

MaCI/GIMnet is free software: you can redistribute it and/or modify it 
under the terms of the GNU Lesser General Public License as published 
by the Free Software Foundation, either version 3 of the License, or 
(at your option) any later version.

MaCI/GIMnet is distributed in the hope that it will be useful, but WITHOUT 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
License for more details.

You should have received a copy of the GNU Lesser General Public 
License along with GIMnet. (See COPYING.LESSER) If not, see 
<http://www.gnu.org/licenses/>.

**/
// -*- coding:iso-8859-15 mode: c++ -*-
/** 
 * \file
 * \brief MaCI_Ranging Logger implementation.
 * \author Matthieu Myrsky <matthieu.myrsky@tkk.fi>
 *
 * $Id: RangingLogger.cpp,v 1.13 2009-11-16 16:07:38 morsko Exp $
 *
 */
#include "RangingLogger.hpp"
#include "gimutils.h"



RangingLogger::RangingLogger(MaCI::Ranging::CRangingClient *aClient,
                             std::string aMaCISLName):
  CSync(1, 1),               
  CThread(1),                
  Logger(),
  iRClient(aClient),
  iRunning(false),
  iRunningThreadStopped(true),
  iFileWriter(),
  iMaCISLName(aMaCISLName),
  iAdditionalInformation("Not active"),
  iMenu()
{

  //  iMenu = new wxMenu();

  //iMenu->Insert(0,0,"LOG TYPES - (Check all for playing with MaCI_Player)");

  iMenu[std::string("Timestamp")]= true;
  iMenu[std::string("Header")]= true;
  iMenu[std::string("Angle")]= true;
  iMenu[std::string("Distance")]= true;
  /*
  wxMenuItem *timestamp = iMenu->InsertCheckItem(1,1,"Timestamp");
  timestamp->Check(true);

  wxMenuItem *hea = iMenu->InsertCheckItem(2,2,"Header");
  hea->Check(true);

  wxMenuItem *ang = iMenu->InsertCheckItem(3,3,"Angle");
  ang->Check(true);


  wxMenuItem *dist = iMenu->InsertCheckItem(4,4,"Distance");
  dist->Check(true);
  */
}



RangingLogger::~RangingLogger(){
  if(iRunning){
    StopLogging();
  }
  //delete iMenu;
}

  
bool RangingLogger::StartLogging(void)
{
  dPrint(10,"Start called");
  if(!iRunning){
    dPrint(5,"Start logging Ranging");
    /*   char buffer[256];
    if(iFilenameSet){
      
     
      sprintf(buffer,"data/%s.txt",
             iFilename.c_str());

    }else{
  
      gim::time tstamp(true);
      tm t;
      //      MaCI::Common::TTimestamp tstamp;
      tstamp.getLocalTime(t);
       
      sprintf(buffer,"data/%s_%.2d_%.2d_%d_%.2d:%.2d:%.2d.txt",
              iMaCISLName.c_str(),
              t.tm_mday,
              t.tm_mon+1,
              t.tm_year+1900,
              t.tm_hour,
              t.tm_min,
              t.tm_sec);
              
     
    }
    dPrint(3,"starting logging to %s",buffer);
    iFile = fopen(buffer,"wt");*/
    iRunning = true; 
    /*    for(int i = 0; i < iMenu->GetMenuItemCount();i++){
      iMenu->Enable(i,false);
      }*/
    RunThread(0);
    return true;
  }

  return false;
}

 
bool RangingLogger::StopLogging(void)
{


  if(iRunning){
    dPrint(5,"Stop logging ranging");
    Lock();
    iRunning = false;
    
    Unlock();
    WaitThread(0);
    /*    for(int i = 0; i < iMenu->GetMenuItemCount();i++){
      iMenu->Enable(i,true);
      }*/
    iFileWriter.CloseFile();
    // fclose(iFile);
    Lock();
    iAdditionalInformation = "Not active";
    Unlock();
    return true;
  }
  return false;
}


int RangingLogger::ThreadFunction(const int aThreadNumber)
{
  using namespace MaCI::Ranging;
  if(aThreadNumber == 0){
    //First the filename
    char buffer[256];
    if(iFilenameSet){
      
     
      sprintf(buffer,"data/%s.txt",
             iFilename.c_str());

    }else{
  
      gim::time tstamp(true);
      tm t;
      //      MaCI::Common::TTimestamp tstamp;
      tstamp.getLocalTime(t);
       
      sprintf(buffer,"data/%s_%.2d_%.2d_%d_%.2d:%.2d:%.2d.txt",
              iMaCISLName.c_str(),
              t.tm_mday,
              t.tm_mon+1,
              t.tm_year+1900,
              t.tm_hour,
              t.tm_min,
              t.tm_sec);
              
     
    }
    std::string filename(buffer);


    int seq = -1;
    TDistanceArray array;
    TDistanceHeader header;
    MaCI::Common::TTimestamp tstamp;
    //Check for the logging types

    bool logTimestamp = iMenu[std::string("Timestamp")];
    bool logHeader =  iMenu[std::string("Header")];
    bool logAngle = iMenu[std::string("Angle")];
    bool logRanges = iMenu[std::string("Distance")];
    int numberOfSavedMeasurement = 0;
    /////////Search the group and instance names :)
    std::string instance;
    std::string group;

    MaCI::MaCICtrl::SMaCISL sl(iMaCISLName);
    if (sl.IsValidFQMaCISL()) {
      group = sl.GetDeviceGroup();
      instance = sl.GetInstance();
    }
    //////////
   
    /*  fprintf(iFile,"%%MaCI_Ranging log file\n");
    fprintf(iFile,"%%Group: %s Instance: %s\n",group.c_str(),instance.c_str());

    fprintf(iFile,"%%");
    if(logTimestamp){
      fprintf(iFile,"timestamp_s timestamp_us ");
    }
    if(logHeader){
      fprintf(iFile,"beam_width beam_count ");
    }
    if(logAngle){
      fprintf(iFile,"angle ");
    }
    if(logRanges){
      fprintf(iFile,"distance ");
    }
    if(logAngle){
      fprintf(iFile,"angle ");
    }
    if(logRanges){
      fprintf(iFile,"distance ");
    }
    fprintf(iFile,"... \n");*/

    TDeviceInformationLimits limits;

    if(!iRClient->GetDeviceLimits(limits)){
      dPrint(1,"Failed to get devicelimits");
    }
    TDeviceInformationPosition dPosition;
    if(!iRClient->GetDevicePosition(dPosition)){
      dPrint(1,"Failed to get devicePosition");
    }
    TRangingHeader hea(limits.max_distance,limits.min_distance, dPosition.x,dPosition.y,dPosition.z,dPosition.heading);
    
    iFileWriter.OpenFile(filename,
                         group,
                         instance,
                         hea);

   
    while(iRunning){
      char buffer2[256];
       if(iRClient->GetDistanceArray(array,
                                    &header, 
                                    &tstamp,
                                    &seq, 
                                    2000)){

         iFileWriter.WriteLine(header,array,tstamp);
         
        Lock();
        /*
        if(logTimestamp){
                   fprintf(iFile,"%u %u %f %u ",tstamp.timestamp_s,tstamp.timestamp_us,header.beam_width,header.beam_count);
        }
        for(unsigned int i = 0; i< header.beam_count;i++){
          if(logAngle){
           fprintf(iFile,"%f ",array[i].angle);
          }
          if(logRanges){
            fprintf(iFile,"%f ", array[i].distance);
          }
        }
        fprintf(iFile,"\n");
        fflush(iFile);
         */
        numberOfSavedMeasurement++;

        Unlock();
      }
      Lock();
      sprintf(buffer2,"%d measurement stored",numberOfSavedMeasurement);
      iAdditionalInformation.clear();
      iAdditionalInformation.assign(buffer2);
      Unlock();
    }
    Lock();
    iRunningThreadStopped = true;
    Unlock();
  }

  return 0;

}

std::string RangingLogger::GetName(){
  return "Ranging Logger";
}


Logger::TMenu *RangingLogger::GetMenu(void){
 
    return &iMenu;
 

}
bool RangingLogger::GetAdditionalInformation(std::string &aInformation){
  Lock();
  aInformation = iAdditionalInformation;
  Unlock();
  return true;
}
bool RangingLogger::SetMenuItem(std::string aItem, bool aValue){ 

  if(!iRunning){
    iMenu[aItem] =  aValue;
    return true;
  }else{
    return false;
  }

}
